<?php

namespace App\Morefun\Wechat;

use App\Entities\Activity;
use App\Entities\Participant;
use EasyWeChat\Support\Arr;

class Service
{
    const SESSION_AUTH_KEY = "wechat_user";
    protected $maker;

    public function __construct(AppMaker $maker)
    {
        $this->maker = $maker;
    }

    public function makeSilentlyAuthorizedUrl($activityId, $setMustFollowingFlag = false)
    {
        $activity = Activity::query()->find($activityId);

        if (!$activity) {
            return '';
        }

        $app = $this->maker->makeByGroupCode($activity->getAttribute('group_code'));
        $args = ['id' => $activityId];

        if ($setMustFollowingFlag) {
            $args['following'] = 1;
        }

        $url = config('api.host') . '/wechat/activities/?' . http_build_query($args);

        $response = $app->oauth
            ->scopes(['snsapi_userinfo'])
            ->setRedirectUrl($url)
            ->redirect();
        return $response->getTargetUrl();
    }

    public function needAuthorization()
    {
        return !isset($_SESSION[self::SESSION_AUTH_KEY]) || empty($_SESSION[self::SESSION_AUTH_KEY]);
    }

    public function gatherUserAndRedirect($id)
    {
        $activity = Activity::with('template')->find($id);

        if (!$activity) {
            abort(404);
        }

        $app = $this->maker->makeByGroupCode($activity->getAttribute('group_code'));

        if ($this->needAuthorization()) {
            $user = $app->oauth->scopes(['snsapi_userinfo'])->user()->toArray();
            $_SESSION[self::SESSION_AUTH_KEY] = $user;
            $openId = Arr::get($user, 'id');
            $vote_token = $this->makeToken($id, $openId);
            $this->gatherUser($user, $id, $vote_token);
        } else {
            $user = $_SESSION[self::SESSION_AUTH_KEY];
            $openId = Arr::get($user, 'id');
            $vote_token = app('redis')->hget('app:uid:'.$id, $openId);
        }

        $url = config('api.host') . $activity->template->url;
        $args = [
            'act_id'        => $id,
            'uid'           => Arr::get($user, 'id'),
            'ways'          => 'wechat',
            'vote_token'    => $vote_token,
            'userName'      => Arr::get($user, 'nickname'),
            'nickname'      => Arr::get($user, 'nickname'),
            'avatar'        => Arr::get($user, 'avatar'),
            'sex'           => Arr::get($user,'original.sex'),
            'city'          =>  Arr::get($user,'original.city'),
            'province'      =>  Arr::get($user,'original.province'),
        ];

        if (isset($_GET['following'])) { // 直接从flowing里拿数据
            $args['following'] = $_GET['following'];
        }

        $query = http_build_query($args);
        $full = sprintf('%s?%s', $url, $query);

        return redirect($full);
    }

    protected function gatherUser(array $user, $act_id, $vote_token)
    {
        $openId = Arr::get($user, 'id');

        if (!$openId) {
            return false;
        }
        app('redis')->hset('app:uid:'.$act_id, $openId, $vote_token);
        
        $profile = [
            'avatar' => Arr::get($user, 'avatar', ''),
            'username' => Arr::get($user, 'name', ''),
            'nickname' => Arr::get($user, 'nickname', ''),
            //'uid' => $openId,
            'source' => 'wechat',
            'sex'           => Arr::get($user,'original.sex'),
            'city'          =>  Arr::get($user,'original.city'),
            'province'      =>  Arr::get($user,'original.province'),
        ];

        return Participant::query()->updateOrCreate(['openid' => $openId], $profile);
    }

    protected function getMillisecond() {
        list($s1, $s2) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 10000);
    }

    protected function makeToken($act_id, $uid) {
        $time = $this->getMillisecond();
        $str = $act_id.$uid.$time.rand(1,10000);
        return md5($str);
    }
}
